package com.ecjtu.stadiumre_servations.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitMQConfig {
    // 交换机名称
    public static final String EXCHANGE_NAME = "venue_booking_exchange";

    /* --------------------- 支付请求相关队列 --------------------- */
    public static final String PAYMENT_REQUEST_QUEUE_NAME = "payment_request_queue";
    public static final String PAYMENT_REQUEST_ROUTING_KEY = "payment.request";

    /* --------------------- 支付结果相关队列 --------------------- */
    public static final String PAYMENT_RESULT_QUEUE_NAME = "payment_result_queue";
    public static final String PAYMENT_RESULT_ROUTING_KEY = "payment.result";

    /* --------------------- 支付超时处理队列 --------------------- */
    public static final String PAYMENT_TIMEOUT_DELAYED_QUEUE_NAME = "payment_timeout_delayed_queue";
    public static final String PAYMENT_TIMEOUT_QUEUE_NAME = "payment_timeout_queue";
    public static final String PAYMENT_TIMEOUT_ROUTING_KEY = "payment.timeout";
    public static final String PAYMENT_TIMEOUT_DELAYED_ROUTING_KEY = "payment.timeout.delayed";

    /* --------------------- 支付通知与退款队列 --------------------- */
    public static final String PAYMENT_NOTICE_QUEUE_NAME = "payment_notice_queue";
    public static final String PAYMENT_NOTICE_ROUTING_KEY = "payment.notice.routing.key";
    public static final String REFUND_RESULT_QUEUE_NAME = "refund_result_queue";
    public static final String REFUND_RESULT_ROUTING_KEY = "refund.result";
    /* --------------------- 拼团超时队列 --------------------- */
    // 拼团超时队列
    public static final String GROUP_ACTIVITY_QUEUE = "group.activity.queue";
    public static final String GROUP_ACTIVITY_ROUTING_KEY = "group.activity.routing.key";
    public static final String GROUP_ACTIVITY_DELAYED_QUEUE = "group.activity.delayed.queue";
    public static final String GROUP_ACTIVITY_DELAYED_ROUTING_KEY = "group.activity.delayed.routing.key";
    /**
     * 创建直连交换机
     */
    @Bean
    public DirectExchange venueBookingExchange() {
        return new DirectExchange(EXCHANGE_NAME, true, false);
    }

    /**
     * 创建支付请求队列
     */
    @Bean
    public Queue paymentRequestQueue() {
        return new Queue(PAYMENT_REQUEST_QUEUE_NAME, true, false, false);
    }

    /**
     * 绑定支付请求队列到交换机
     */
    @Bean
    public Binding bindingPaymentRequest() {
        return BindingBuilder.bind(paymentRequestQueue())
                .to(venueBookingExchange())
                .with(PAYMENT_REQUEST_ROUTING_KEY);
    }

    /**
     * 创建支付结果队列
     */
    @Bean
    public Queue paymentResultQueue() {
        return new Queue(PAYMENT_RESULT_QUEUE_NAME, true, false, false);
    }

    /**
     * 绑定支付结果队列到交换机
     */
    @Bean
    public Binding bindingPaymentResult() {
        return BindingBuilder.bind(paymentResultQueue())
                .to(venueBookingExchange())
                .with(PAYMENT_RESULT_ROUTING_KEY);
    }

    /**
     * 创建支付超时延迟队列（配置TTL和死信交换机）
     */
    @Bean
    public Queue paymentTimeoutDelayedQueue() {
        Map<String, Object> args = new HashMap<>();
        // 设置队列的TTL（30分钟）
        args.put("x-message-ttl", 3 * 60 * 1000);
        // 设置死信交换机（消息过期后转发到实际处理队列）
        args.put("x-dead-letter-exchange", EXCHANGE_NAME);
        // 设置死信路由键
        args.put("x-dead-letter-routing-key", PAYMENT_TIMEOUT_ROUTING_KEY);
        return new Queue(PAYMENT_TIMEOUT_DELAYED_QUEUE_NAME, true, false, false, args);
    }

    /**
     * 绑定支付超时延迟队列到交换机
     */
    @Bean
    public Binding bindingPaymentTimeoutDelayed() {
        return BindingBuilder.bind(paymentTimeoutDelayedQueue())
                .to(venueBookingExchange())
                .with(PAYMENT_TIMEOUT_DELAYED_ROUTING_KEY);
    }

    /**
     * 创建支付超时实际处理队列
     */
    @Bean
    public Queue paymentTimeoutQueue() {
        return new Queue(PAYMENT_TIMEOUT_QUEUE_NAME, true, false, false);
    }

    /**
     * 绑定支付超时队列到交换机
     */
    @Bean
    public Binding bindingPaymentTimeout() {
        return BindingBuilder.bind(paymentTimeoutQueue())
                .to(venueBookingExchange())
                .with(PAYMENT_TIMEOUT_ROUTING_KEY);
    }

    /**
     * 创建支付通知队列
     */
    @Bean
    public Queue paymentNoticeQueue() {
        return new Queue(PAYMENT_NOTICE_QUEUE_NAME, true, false, false);
    }

    /**
     * 绑定支付通知队列到交换机
     */
    @Bean
    public Binding bindingPaymentNotice() {
        return BindingBuilder.bind(paymentNoticeQueue())
                .to(venueBookingExchange())
                .with(PAYMENT_NOTICE_ROUTING_KEY);
    }

    /**
     * 创建退款结果队列
     */
    @Bean
    public Queue refundResultQueue() {
        return new Queue(REFUND_RESULT_QUEUE_NAME, true, false, false);
    }

    /**
     * 绑定退款结果队列到交换机
     */
    @Bean
    public Binding bindingRefundResult() {
        return BindingBuilder.bind(refundResultQueue())
                .to(venueBookingExchange())
                .with(REFUND_RESULT_ROUTING_KEY);
    }
    /**
     * 创建拼团结果超时队列
     */
    /**
     * 创建拼团结果超时延迟队列（配置TTL和死信交换机）
     */
    @Bean
    public Queue groupActivityDelayedQueue() {
        Map<String, Object> args = new HashMap<>();
        // 设置队列的TTL，例如 1 小时
//        args.put("x-message-ttl", 24*60 * 60 * 1000);
        args.put("x-message-ttl",  3*60 * 1000);
        // 设置死信交换机（消息过期后转发到实际处理队列）
        args.put("x-dead-letter-exchange", EXCHANGE_NAME);
        // 设置死信路由键
        args.put("x-dead-letter-routing-key", GROUP_ACTIVITY_ROUTING_KEY);
        return new Queue(GROUP_ACTIVITY_DELAYED_QUEUE, true, false, false, args);
    }
    /**
     * 绑定拼团结果超时延迟队列到交换机
     */
    @Bean
    public Binding bindingGroupActivityDelayed() {
        return BindingBuilder.bind(groupActivityDelayedQueue())
                .to(venueBookingExchange())
                .with(GROUP_ACTIVITY_DELAYED_ROUTING_KEY);
    }

    /**
     * 创建拼团结果超时实际处理队列
     */
    @Bean
    public Queue groupActivityQueue() {
        return new Queue(GROUP_ACTIVITY_QUEUE, true);
    }

    /**
     * 绑定拼团结果超时队列到交换机
     */
    @Bean
    public Binding groupActivityBinding() {
        return BindingBuilder.bind(groupActivityQueue())
                .to(venueBookingExchange())
                .with(GROUP_ACTIVITY_ROUTING_KEY);
    }
}